package servlet;

import com.fasterxml.jackson.databind.ObjectMapper;

import dao.CategoryDao;

import entity.Category;

import utils.ServerResponse;



import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

import java.util.Objects;



@WebServlet(name = "CategoryServlet",urlPatterns = {"/category"})

public class CategoryServlet extends HttpServlet {

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //获取客户端发出的请求，

        String action=request.getParameter("action");

        //把服务器端的数据转换成字符串

        ObjectMapper objectMapper=new ObjectMapper();



        //根据id关键字删除指定的记录

        if("deleteByPrimaryKey".equals(action)){

            //获取id关键字

            int id=Integer.parseInt(request.getParameter("id"));

            String str=null;

            //获取当前要删除记录信息，并保存在商品对象中

            Category category=CategoryDao.selectByPrimaryKey(id);

            //判断删除是否成功，若删除成功则把它下面的结点级别提升上来，

            if(CategoryDao.deleteByPrimaryKey(id)){

                //判断父结点为id的子结点是否存在，存在我们将进行递归调用进行提升（若级别然来是2就变成1）

                if(CategoryDao.getRecordCount(id)>0){

                    //获取以被删除结点为父类的所有孩子结点。

                    List<Category> list=CategoryDao.selectCategoryChildrenByParentId(id);

                    //通过递归调用把被删除结点的孩子的级别提升起来。

                    recursiveChildrenParentidandLevel(list,category.getParent_id(),category.getLevel()-1);

                }

                //把成功的json数据格式转换成字符串

                str=objectMapper.writeValueAsString(ServerResponse.createBySuccessMessage("删除商品分类成功"));

                //输出json格式字符串输出到客户端

                response.getWriter().println(str);

            }else{

                //把失败的json数据格式转换成字符串

                str=objectMapper.writeValueAsString(ServerResponse.createByErrorMessage("删除商品分类失败"));

                //输出json格式字符串输出到客户端

                response.getWriter().println(str);

            }

        }



        //添加操作（若action发出的是insert操作就进行添加操作）

        if("insert".equals(action)){

            //获取父类的id，因父类是整形的所以，要把它进行转换成整形数据

            int parent_id=Integer.parseInt(request.getParameter("parent_id"));

            //获取商品分类名称

            String name=request.getParameter("name");

            //获取商品级别

            int level=Integer.parseInt(request.getParameter("level"));

            //创建商品分类对角。

            Category cate=new Category();

            //下面商品分类对象属性赋值

            cate.setParent_id(parent_id);

            //修改名称

            cate.setName(name);

            //状态为1正常，2表示废弃

            cate.setStatus(1);

            //更改后是级别加1

            cate.setLevel(parent_id+1);

            String str=null;

            //添加分类成功，返回成功的json数据格式，否则返回失败的json数据格式

            if(CategoryDao.insert(cate)){

                //把成功的json数据格式转换成字符串

                str=objectMapper.writeValueAsString(ServerResponse.createBySuccessMessage("添加商品分类成功"));

                //输出json字符串到客户端

                response.getWriter().println(str);

            }else{

                //把失败的json数据格式转换成字符串

                str=objectMapper.writeValueAsString(ServerResponse.createByErrorMessage("添加商品分类失败"));

                //输出json字符串到客户端

                response.getWriter().println(str);

            }

        }



        //更新操作

        if("updateByPrimaryKey".equals(action)){

            //获取的id，因id是整形的所以，要把它进行转换成整形数据

            int id=Integer.parseInt(request.getParameter("id"));

            //获取父类的id，因父类是整形的所以，要把它进行转换成整形数据

            int parent_id=Integer.parseInt(request.getParameter("parent_id"));

            //获取商品分类名称

            String name=request.getParameter("name");

            //获取类别状态，1表示正常，2表示废弃

            int status=Integer.parseInt(request.getParameter("status"));

            //获取商品类别(父类的级别）

            int parent_level=Integer.parseInt(request.getParameter("level"));

            //创建商品分类对象

            Category cate=new Category();

            //给对象属性赋值

            cate.setId(id);

            cate.setParent_id(parent_id);

            cate.setName(name);

            cate.setStatus(status);

            cate.setLevel(parent_level+1);

            String str=null;

            //更新成功返回成功的json数据格式，否则返回失败的json数据格式

            if(CategoryDao.updateByPrimaryKey(cate)){

                //更新分类结点和它的子结点，采用递归调用来完成

                recursiveChildrenLevel(id,parent_level+1);

                //把成功的json数据格式转换成字符串

                str=objectMapper.writeValueAsString(ServerResponse.createBySuccessMessage("更新商品分类成功"));

                //输出json字符串到客户端

                response.getWriter().println(str);

            }else{

                //把失败的json数据格式转换成字符串

                str=objectMapper.writeValueAsString(ServerResponse.createByErrorMessage("更新商品分类失败"));

                //输出json字符串到客户端

                response.getWriter().println(str);

            }

        }



        //按分页方式获取相应页的记录

        if("selectCategory".equals(action)){

            //定义商品分类集合

            List<Category> list=null;

            String str=null;

            //记录总娄

            int total=0;

            //每页的记录个数

            int pagenum=Integer.parseInt(request.getParameter("pagenum"));

            //第几页的记录

            int pagesize=Integer.parseInt(request.getParameter("pagesize"));

            //访问条件要清除

            String query=request.getParameter("query").trim();

            //判断条件是否为空，若为空则获取所有记录，否则只返回满足条件的记录

            if(query == "" || query==null){

                //条件为空

                list=CategoryDao.selectCategory(pagenum,pagesize);

                //没有条件的记录总数

                total=CategoryDao.getRecordCount();

            }else{

                //条件不为空，

                list=CategoryDao.selectCategory(query,pagenum,pagesize);

                //条件不为空的记录总数

                total=CategoryDao.getRecordCount(query);

            }

            //判断商品分类不为空，则返回带有记录总数的json格式，否则返回获取商品分类失败

            if(list !=null && list.size()>0){

                //有记录，并把json数据格式转换成字符串

                str=objectMapper.writeValueAsString(ServerResponse.createBySuccess("获取商品分类成功",list));

                //把记录总数连接在json字符串中

                str="{\"total\":"+total+","+str.substring(1,str.length());

                //输出json格式字符串输出到客户端

                response.getWriter().println(str);

            }else{

                //把失败的json数据格式转换成字符串

                str=objectMapper.writeValueAsString(ServerResponse.createByErrorMessage("获取商品分类失败"));

                //输出json格式字符串输出到客户端

                response.getWriter().println(str);

            }



        }





        if("getcatedata".equals(action)){

            System.out.println("getcatedata");

            int id=Integer.parseInt(request.getParameter("parent_id"));

            List<Category> list=null;

            list = CategoryDao.selectCategoryChildrenByParentId(id);

            List<Category> resultList=parseMenuTree(list);

            ObjectMapper objectMapper1=new ObjectMapper();

            String str="";

            str=objectMapper.writeValueAsString(ServerResponse.createBySuccess("获取商品分类成功",resultList)).replace("\"children\":[],","");

            response.getWriter().println(str);

            System.out.println(str);

        }





        if("getcate".equals(action)){

            //定义用于存放记录总数

            int total=0;

            //获取分页变量pagenum（它代表的是第几页）

            int pagenum=Integer.parseInt(request.getParameter("pagenum"));

            //获取分页变量pagesize(它代表的是一页里，显示多少条记录

            int pagesize=Integer.parseInt(request.getParameter("pagesize"));

            //根据分页获取相应的记录

            List<Category> list =CategoryDao.selectCategory(pagenum,pagesize);

            //获取记录的总数

            total=CategoryDao.getRecordCount();

            System.out.println(list);

            //TODO 这里从数据库获取全量菜单后放到list中

            //树形结构获取数据（因为Category实体类是包含自身的结点

            List<Category> result = parseMenuTree(list);

            //创建ObjectMapper类的对象，把json数据格式转换成字符串

            ObjectMapper objectMapper1=new ObjectMapper();

            String str="";

            //把转换后的字符串中空的字符串清除掉

            str=objectMapper.writeValueAsString(ServerResponse.createBySuccess("获取商品分类成功",result)).replace("\"children\":[],","");

            //在转换后的字符串中添加记录总数

            str="{\"total\":"+total+","+str.substring(1,str.length());

            //输出到客户端

            response.getWriter().println(str);

        }

    }



    /**

     * 表示客户可以采用get访问后台主页

     * @param request  前台提交数据

     * @param response  后台向前台输出数据

     * @throws ServletException

     * @throws IOException

     */

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //当用户采用get方式调用后台时，给doPost（）方法进行处理

        doPost(request, response);

    }



    /**

     * 获取分类的焦点

     * @param list  分类结点

     * @return  返回分类结点

     */

    public static List<Category> parseMenuTree(List<Category> list){

        List<Category> result = new ArrayList<Category>();

        // 1、获取第一级节点

        for (Category menu : list) {

            if(0 == menu.getParent_id()) {

                result.add(menu);

            }

        }

        // 2、递归获取子节点

        for (Category parent : result) {

            //递归调用

            parent = recursiveTree(parent, list);

        }

        return result;

    }



    /**

     * 递归调用获取结点的子结点。

     * @param parent 父结点

     * @param list  父结点下的子结点

     * @return  返回父结点下的子结点

     */

    public static Category recursiveTree(Category parent, List<Category> list) {

        //遍历每一个结点

        for (Category menu : list) {

            //判断子结点的父结点id是否与父结点id一样，若一样则继续递归调用

            if(Objects.equals(parent.getId(),menu.getParent_id())) {

                //递归谢用

                menu = recursiveTree(menu, list);

                //parent结点添加子结点。

                parent.getChildren().add(menu);

            }

        }

        //返回所有结点

        return parent;

    }



    /**

     * 采用递归调用修改商品分类某一点和这上点下子分类父结点和分类级。

     * @param parent_id 父结点id

     * @param level 分类级别

     */

    public static void recursiveChildrenLevel(int parent_id, int level) {

        //根据parent_id值获取父类的信息

        List<Category> list=CategoryDao.selectCategoryChildrenByParentId(parent_id);

        if(list !=null && list.size()>0) {

            //遍历集合的元素

            for (Category child : list) {

                //根据parent_id值，修改相应记录的父类parent_id和分类级别level

                CategoryDao.updateLevelById(child.getId(), level + 1);

                //判断元素是否有子元素。有了就递归调用。

                if (CategoryDao.getRecordCount(child.getId()) > 0) {

                    //递归调用，对相应元素下的结点的级别进行修改

                    recursiveChildrenLevel(child.getId(), level + 1);

                }

            }

        }

    }



    /**

     * 修改时需要递归调用该方法实现后面结点改变

     * @param list 商品分类集合

     * @param parent_id 父类结点

     * @param level 级别

     */

    public static void recursiveChildrenParentidandLevel(List<Category> list,int parent_id, int level) {

        //判断集合是否存在元素，若存在则进行修改

        if(list !=null && list.size()>0) {

            //遍历信息元素

            for (Category child : list) {

                //根据id修改parent_id和level。

                CategoryDao.updateParentidAndLevelById(parent_id,level+1,child.getId());

                //判断子结点是否成子结点。有了就递归调用进行处理。

                if (CategoryDao.getRecordCount(child.getId()) > 0) {

                    //递归调用修改结点的子结点

                    recursiveChildrenParentidandLevel(CategoryDao.selectCategoryChildrenByParentId(child.getId()),child.getParent_id(),level + 1);

                }

            }

        }

    }

}

